home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks97 / WarriorsProgress.sit / Warrior’s Progress / source code / Source / Libraries / Windows / Window.cp < prev    next >
Text File  |  1997-06-28  |  8KB  |  353 lines

  1. // Window.cp
  2.  
  3. #ifndef Window_h
  4. #include "Window.h"
  5. #endif
  6. #ifndef WindowDefinition_h
  7. #include "WindowDefinition.h"
  8. #endif
  9. #ifndef WindowUpdater_h
  10. #include "WindowUpdater.h"
  11. #endif
  12. #ifndef MouseDownEvent_h
  13. #include "MouseDownEvent.h"
  14. #endif
  15. #ifndef View_h
  16. #include "View.h"
  17. #endif
  18. #ifndef TangibleView_h
  19. #include "TangibleView.h"
  20. #endif
  21. #ifndef ContextMaintainer_h
  22. #include "ContextMaintainer.h"
  23. #endif
  24. #ifndef GraphicsDeviceObject_h
  25. #include "GraphicsDeviceObject.h"
  26. #endif
  27. #ifndef MenuBar_h
  28. #include "MenuBar.h"
  29. #endif
  30. #ifndef WindowInitializer_h
  31. #include "WindowInitializer.h"
  32. #endif
  33. #ifndef Application_h
  34. #include "Application.h"
  35. #endif
  36. #ifndef BroadcastLoop_h
  37. #include "BroadcastLoop.h"
  38. #endif
  39. #ifndef WindowPile_h
  40. #include "WindowPile.h"
  41. #endif
  42. #ifndef WindowLocation_h
  43. #include "WindowLocation.h"
  44. #endif
  45. #ifndef ViewMap_h
  46. #include "ViewMap.h"
  47. #endif
  48.  
  49. Window::Window( const WindowDefinition& theDefinition )
  50.   : WindowController( visibility, zoomed, bounds, name, index ),
  51.      Receiver<PreparingToQuit>( Application::The() ),
  52.      definition( theDefinition ),
  53.      window( theDefinition.Procedure(), theDefinition.Closeable() ),
  54.      pane( window ),
  55.      context( &window.port ),
  56.      registration( &window.port, this ),
  57.      closingLink( focus, *this ),
  58.      visibility( *this, &Window::GetVisibility, &Window::SetVisibility ),
  59.      zoomed( *this, &Window::GetZoomed, &Window::SetZoomed ),
  60.      bounds( *this, &Window::GetBounds, &Window::SetBounds ),
  61.      name( *this, &Window::GetName, &Window::SetName ),
  62.      index( *this, &Window::GetIndex, &Window::SetIndex )
  63.   {
  64.     WindowLocator::Register( registration );
  65.   }
  66.  
  67. Window::~Window()
  68.   {
  69.   }
  70.  
  71. void Window::Initialize( const WindowInitializer& initializer )
  72.   {
  73.     SetName( initializer.NameFor( *this ) );
  74.     SetBounds( initializer.PositionFor( *this ) );
  75.     if ( initializer.VisibilityFor( *this ) )
  76.         SetIndex( initializer.IndexFor( *this ) );
  77.   }
  78.  
  79. void Window::Update()
  80.   {
  81.     ContextMaintainer cm( &context );
  82.  
  83.     WindowUpdater updater( &window.port );
  84.     
  85.     View& view( *pane );
  86.     view.SetContext();
  87.     ViewMap map( view );
  88.     
  89.     if ( map.Visible() )
  90.         view.Draw( map );
  91.   }
  92.  
  93. void Window::Activate()
  94.   {
  95.     focus.BeFavored();
  96.     Assert( focus.Active() );
  97.   }
  98.  
  99. void Window::Deactivate()
  100.   {
  101.     focus.BeDisfavored();
  102.     Assert( !focus.Active() );
  103.   }
  104.  
  105. void Window::ClickContent( const MouseDownEvent& event )
  106.   {
  107.     ContextMaintainer cm( &context );
  108.     
  109.     PointObject hit( event.Where() );
  110.     hit.GlobalToLocal();
  111.     
  112.     TangibleView *view = pane->Touch( hit );
  113.     if ( view != 0 && ( !event.Activating() || view->WantsActivatingClick() ) )
  114.       {
  115.         view->SetContext();
  116.         view->Click( hit, event );
  117.       }
  118.     
  119.     if ( FrontWindow() != &window.port )
  120.         index.Set( 1 );
  121.   }
  122.  
  123. void Window::ClickDrag( const MouseDownEvent& event )
  124.   {
  125.     if ( event.Activating() && !event.Command() )
  126.         index.Set( 1 );
  127.     
  128.     window.MoveByDragging( event.Where() );
  129.     bounds = bounds;            // To help with recording
  130.   }
  131.  
  132. void Window::ClickClose( const MouseDownEvent& event )
  133.   {
  134.     if ( window.TrackCloseBox( event.Where() ) )
  135.         Close();
  136.   }
  137.  
  138. void Window::ClickZoomIn( const MouseDownEvent& event )
  139.   {
  140.     if ( window.TrackZoomInBox( event.Where() ) )
  141.         zoomed.Set( !GetZoomed() );
  142.   }
  143.  
  144. void Window::ClickZoomOut( const MouseDownEvent& event )
  145.   {
  146.     if ( window.TrackZoomOutBox( event.Where() ) )
  147.         zoomed.Set( !GetZoomed() );
  148.   }
  149.  
  150. void Window::ClickGrow( const MouseDownEvent& event )
  151.   {
  152.     PointObject newSize = window.SizeByDragging( event.Where(),
  153.                                                                  pane->MinimumSize(),
  154.                                                                  pane->MaximumSize() );
  155.      
  156.      Rectangle newBounds( window.GlobalBounds() );
  157.      newBounds.SetBottomRight( newBounds.TopLeft() + newSize );
  158.      
  159.      bounds.Set( newBounds );
  160.   }
  161.  
  162. bool Window::GetVisibility() const
  163.   {
  164.     return window.Visible();
  165.   }
  166.  
  167. void Window::SetVisibility( bool toShow )
  168.   {
  169.     if ( toShow )
  170.         window.Show();
  171.      else
  172.         window.Hide();
  173.   }
  174.  
  175. bool Window::GetZoomed() const
  176.   {
  177.     return window.GlobalBounds() == BestBounds();
  178.   }
  179.  
  180. void Window::SetZoomed( bool toZoom )
  181.   {
  182.     if ( toZoom )
  183.       {
  184.         window.SetStandardBounds( BestBounds() );
  185.         window.ZoomToStandardBounds();
  186.       }
  187.      else
  188.         window.ZoomToUserBounds();
  189.  
  190.     pane.UpdateBounds();
  191.   }
  192.  
  193. Rectangle Window::GetBounds() const
  194.   {
  195.     return window.GlobalBounds();
  196.   }
  197.  
  198. void Window::SetBounds( Rectangle newBounds )
  199.   {
  200.     window.SetBounds( newBounds );
  201.     pane.UpdateBounds();
  202.   }
  203.  
  204. ConstPString Window::GetName() const
  205.   {
  206.     return nameString;
  207.   }
  208.  
  209. void Window::SetName( ConstPString newName )
  210.   {
  211.     nameString = newName;
  212.     window.SetTitle( newName );
  213.   }
  214.  
  215. uint32 Window::GetIndex() const
  216.   {
  217.     return window.Index();
  218.   }
  219.  
  220. void Window::SetIndex( uint32 newIndex )
  221.   {
  222.     window.SetIndex( newIndex );
  223.   }
  224.  
  225. GDHandle Window::DefaultScreen() const
  226.   {
  227.     WindowObject *front = WindowObject::Front();
  228.     return front == 0
  229.                 ? GraphicsDeviceObject::Main()
  230.                 : front->NearestScreen();
  231.   }
  232.  
  233. Rectangle Window::DefaultPosition( GDHandle screen ) const
  234.   {
  235.     Rectangle available( AvailableArea( screen ) );
  236.     PointObject bestSize = pane->BestSize( available.Size() );
  237.     PointObject reasonableSize = pane->ReasonableSize();
  238.     
  239.     Rectangle bestPile;
  240.     uint32 bestPileScore = maxuint32;
  241.  
  242.     for ( WindowPile pile( available, bestSize );
  243.             pile.Unfinished() && bestPileScore > 0;
  244.             pile++ )
  245.       {
  246.         uint32 score = WindowObject::CountVisibleWindows( *pile );
  247.         
  248.         if ( score >= bestPileScore )
  249.             continue;
  250.  
  251.         bestPileScore = score;
  252.         bestPile = *pile;
  253.       }
  254.         
  255.     PointObject bestLocation;
  256.     uint32 bestLocationScore = maxuint32;
  257.     
  258.     for ( WindowLocation location( bestPile, reasonableSize );
  259.             location.Unfinished() && bestLocationScore > 0;
  260.             location++ )
  261.       {
  262.         Rectangle nearby( *location, *location );
  263.         nearby.Outset( 5 );
  264.         uint32 score = WindowObject::CountVisibleWindows( nearby );
  265.         
  266.         if ( score >= bestLocationScore )
  267.             continue;
  268.  
  269.         bestLocationScore = score;
  270.         bestLocation = *location;
  271.       }
  272.     
  273.     bestSize = pane->BestSize( available.BottomRight() - bestLocation );
  274.  
  275.     return Rectangle( bestLocation, bestLocation + bestSize );
  276.   }
  277.  
  278. bool Window::CanClose() const
  279.   {
  280.     return definition.Closeable();
  281.   }
  282.  
  283. void Window::Close( SavingOption savingOption )
  284.   {
  285.     for ( BroadcastLoop<PreparingToClose> receiver( *this );
  286.             receiver.Unfinished();
  287.             receiver++ )
  288.         receiver->PrepareToClose( savingOption );
  289.     
  290.     window.Hide();
  291.     focus.BeDisfavored();
  292.     delete this;
  293.   }
  294.  
  295. void Window::PrepareToQuit( SavingOption savingOption )
  296.   {
  297.     Close( savingOption );
  298.   }
  299.  
  300. GDHandle Window::BestScreen() const
  301.   {
  302.     return window.NearestScreen();
  303.   }
  304.  
  305. Rectangle Window::BestBounds() const
  306.   {
  307.     return BestBounds( BestScreen() );
  308.   }
  309.  
  310. Rectangle Window::BestBounds( GDHandle screen ) const
  311.   {
  312.     return BestBounds( AvailableArea( screen ) );
  313.   }
  314.  
  315. Rectangle Window::BestBounds( Rectangle available ) const
  316.   {
  317.     Rectangle best( window.GlobalBounds() );
  318.     
  319.     best.SetBottomRight( best.TopLeft() + pane->BestSize( available.Size() ) );
  320.     
  321.     if ( best.right > available.right )
  322.         best += PointObject( available.right - best.right, 0 );
  323.     
  324.     if ( best.bottom > available.bottom )
  325.         best += PointObject( 0, available.bottom - best.bottom );
  326.     
  327.     if ( best.left < available.left )
  328.         best += PointObject( available.left - best.left, 0 );
  329.     
  330.     if ( best.top < available.top )
  331.         best += PointObject( 0, available.top - best.top );
  332.                     
  333.     return best;
  334.   }
  335.  
  336. Rectangle Window::AvailableArea( GDHandle theScreen ) const
  337.   {
  338.     GraphicsDeviceObject screen( theScreen );
  339.     
  340.     Rectangle area( screen.Bounds() );
  341.     
  342.     if ( screen.IsMainScreen() )
  343.         area.top += MenuBar::The().Height();
  344.     
  345.     area.Inset( 3 );
  346.     
  347.     area.Inset( definition.FrameSize() );
  348.     
  349.     return area;
  350.   }
  351.  
  352. #include "BroadcastLoop.cp"
  353.